package com.fg.core;

import com.fg.exception.NormalTerminationException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.stereotype.Component;

/**
 * @author 王富贵·lixiang
 * @since 2024/04/22 11:31
 * mapper正常退出异常代理类
 */
@Slf4j
@Aspect
@Component
public class MapperExceptionAspect {

    /**
     * 捕获com.fg.mapper和service包下所有类的所有方法的异常,判断是否是NormalTerminationException
     */
    @Around("execution(* com.fg.mapper..*.*(..)) || execution(* com.fg.service..*.*(..))")
    public Object aroundMapperExecution(ProceedingJoinPoint joinPoint) {
        try {
            joinPoint.proceed();
        } catch (Throwable e) {
            if (e instanceof MyBatisSystemException) {
                if (((MyBatisSystemException) e).getRootCause() instanceof NormalTerminationException) {
                    log.info("正常执行完毕");
                } else {
                    log.error("mybatis-plus出现其他异常情况", e);
                }
            } else {
                log.error("出现非mybatis-plus的异常情况", e);
            }
        }
        return getDefaultReturnValue(joinPoint);
    }

    /**
     * 默认返回值
     */
    private Object getDefaultReturnValue(ProceedingJoinPoint joinPoint) {
        // 获取目标方法的返回类型
        Class<?> returnType = ((MethodSignature) joinPoint.getSignature()).getReturnType();
        if (returnType.isPrimitive()) {
            // 返回基本类型的默认值
            if (Boolean.TYPE.equals(returnType)) {
                return false;
            } else if (Integer.TYPE.equals(returnType)) {
                return 0;
            } else if (Double.TYPE.equals(returnType)) {
                return 0.0d;
            } else if (Float.TYPE.equals(returnType)) {
                return 0.0f;
            } else if (Long.TYPE.equals(returnType)) {
                return 0L;
            } else if (Character.TYPE.equals(returnType)) {
                return '\u0000';
            } else if (Byte.TYPE.equals(returnType)) {
                return (byte) 0;
            } else if (Short.TYPE.equals(returnType)) {
                return (short) 0;
            }
        }
        // 如果不是基本类型，则返回null
        return null;
    }
}
